﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;

namespace QuakeStats
{
    class LogParser
    {

        private string _fileName;

        public LogParser(string fileName)
        {
            _fileName = fileName;
        }

        private Dictionary<string, ClientInfoEntry> InitializeCurrentClients()
        {
            // Since <world> is who does the killing when you crater, fall off the map, etc. it's listed as a player and logged appropriately.
            Dictionary<string, ClientInfoEntry> currentClients = new Dictionary<string, ClientInfoEntry>();
            string foo = @" 00:00 ClientUserinfoChanged: 1022 n\<world>\t\3\model\visor/gorre\hmodel\visor/gorre\g_redteam\\g_blueteam\\c1\4\c2\5\hc\100\w\0\l\0\tt\0\tl\0";
            ClientInfoEntry entry = new ClientInfoEntry(foo);
            currentClients.Add("1022", entry);

            return currentClients;
        }

        public void ProcessLogFile()
        {
            Dictionary<string, ClientInfoEntry> currentClients = InitializeCurrentClients();




            GameEntry currentGame = null;

            using (StreamReader sr = File.OpenText(_fileName))
            {
                string readLine = sr.ReadLine();
                while (!string.IsNullOrEmpty(readLine))
                {

                    #region Console Writing
                    LogEntryType entryType = LogEntry.GetLogEntryType(readLine);
                    if (readLine.Length > 80)
                        Console.WriteLine(readLine.Substring(0, 70) + ". . .");
                    else
                        Console.WriteLine(readLine);
                    #endregion



                    switch (entryType)
                    {
                        case LogEntryType.ClientUserInfo:
                            ClientInfoEntry clientInfo = new ClientInfoEntry(readLine);
                            if (currentClients.ContainsKey(clientInfo.ClientId))
                                currentClients[clientInfo.ClientId] = clientInfo;
                            else
                                currentClients.Add(clientInfo.ClientId, clientInfo);
                            break;

                        case LogEntryType.Item:
                            ItemEntry entry = new ItemEntry(readLine);
                            if (entry.DbItem != null)
                            {
                                Item_Player itmPlayer = new Item_Player();
                                itmPlayer.Item = entry.DbItem;
                                itmPlayer.PlayerId = currentClients[entry.ClientId].DbPlayer.PlayerId;
                                itmPlayer.RetrievalDate = entry.MasterTime;
                                SingleContext.Instance.AddToItem_Player(itmPlayer);
                                SingleContext.Instance.SaveChanges();
                            }
                            break;

                        case LogEntryType.Kill:
                            KillEntry killEntry = new KillEntry(readLine);
                            Death death = new Death();
                            if (currentGame != null && currentGame.DbGame != null)
                                death.Game = currentGame.DbGame;
                            death.WeaponId = killEntry.WeaponId;
                            death.VictimId = currentClients[killEntry.VictimId].DbPlayer.PlayerId;
                            death.TimeOfDeath = killEntry.MasterTime;
                            death.KillerId = currentClients[killEntry.KillerId].DbPlayer.PlayerId;
                            SingleContext.Instance.AddToDeaths(death);
                            SingleContext.Instance.SaveChanges();
                            break;

                        case LogEntryType.InitGame:
                            GameEntry gameEntry = new GameEntry(readLine);
                            // Peek to see if the next line is 'warmup or not'
                            string nextLine = sr.ReadLine();
                            gameEntry.IsWarmup = (LogEntry.GetLogEntryType(nextLine) == LogEntryType.Warmup);
                            if (!gameEntry.IsWarmup)
                            {
                                gameEntry.InitGameDb();
                                currentGame = gameEntry;
                            }
                            break;

                        case LogEntryType.Warmup:
                            break;

                        case LogEntryType.ClientConnect:
                            break;

                        case LogEntryType.ClientBegin:
                            break;

                        case LogEntryType.ShutdownGame:
                            LogEntry shutdown = new LogEntry(readLine);
                            if (currentGame != null && !currentGame.IsWarmup)
                            {
                                currentGame.SetEndDate(shutdown.Time);
                                SingleContext.Instance.SaveChanges();
                            }
                            currentGame = null;
                            break;

                        case LogEntryType.Dash:
                            break;

                        case LogEntryType.ClientDisconnect:
                            ClientDisconnectEntry disconnect = new ClientDisconnectEntry(readLine);
                            if (currentClients.ContainsKey(disconnect.ClientId))
                                currentClients.Remove(disconnect.ClientId);
                            break;

                        case LogEntryType.Exit:
                            break;

                        case LogEntryType.Score:
                            ScoreEntry score = new ScoreEntry(readLine);
                            Score dbScore = new Score();
                            dbScore.PlayerId = currentClients[score.ClientId].DbPlayer.PlayerId;
                            if (currentGame != null)
                                dbScore.Game = currentGame.DbGame;
                            dbScore.Team = (currentClients[score.ClientId].Team == "1") ? "Red" : "Blue";
                            dbScore.Score1 = score.Score;
                            dbScore.TimeScored = score.MasterTime;
                            SingleContext.Instance.AddToScores(dbScore);
                            SingleContext.Instance.SaveChanges();
                            break;

                        case LogEntryType.TeamScore:
                            if (currentGame != null)
                            {
                                currentGame.TeamScore = new TeamScoreEntry(readLine);
                                SingleContext.Instance.SaveChanges();
                            }
                            break;

                        case LogEntryType.Say: // do nothing
                            break;

                        case LogEntryType.SayTeam: // do nothing
                            break;

                        default:
                            break;


                    }


                    readLine = sr.ReadLine();
                }
            }




        }
    }
}
